package com.yudean.esb.plugins.component;

import com.yudean.esb.dao.esb.EsbServiceHelperDao;
import com.yudean.esb.util.SpringUtil;

import java.io.Serializable;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
 * @author Lei Duan <duanlei#gdyd.com>
 * @version 1.0.0
 * @since 2013-10-21@16
 */

public class SelfMappers implements Serializable {
    private static final long serialVersionUID = 5492840137378851336L;
    private String tbName;
    private Map<String, String> primaryMap = null;
    private Map<String, String> aliasMap = null;
    private Map<String, Map<String, String>> subMap = null;
    private Map<String, Map<String, String>> relationMap = null;
    /**
     * 需要检查权限的字段*
     */
    private Map<String, String> authMap = null;
    /**
     * 可以查询的字段 key表示发送过来的字段node
     */
    private Map<String, String> queryMap = null;
    /**
     * 数据类型的字段 key表示发送过来的字段node
     */
    private Map<String, String> dataTypeMap = null;
    private String select;
    private String from;
    private String where;


    public SelfMappers(String serviceID) {
        if (serviceID != null && !"".equals(serviceID.trim())) {
            EsbServiceHelperDao esbServiceHelperDao = (EsbServiceHelperDao) SpringUtil.getBean("esbServiceHelperDao");
            //主表名
            this.tbName = esbServiceHelperDao.getTableNameByServiceID(serviceID);       //表名（配置表：ESB_SERVICE_CONFIG）
            // 主表
            this.primaryMap = esbServiceHelperDao.getPrimaryServiceMap(serviceID);      //数据库列名和属性对应 相当于ResultMap
            // aliase name                                                                     payment IDS_AP_CON_PAYMENTS_INT
            this.aliasMap = esbServiceHelperDao.getPolymericServiceMap(serviceID);      //别名  contract  IDS_AP_CONTRACT_INT
            //sub map
            this.subMap = esbServiceHelperDao.getSubServiceMapMap(serviceID);           //子表名 列名 属性名
            // relation
            this.relationMap = esbServiceHelperDao.getSubRelationMapMap(serviceID);     //ESB_SERVICE_SUB_MAPPER TB_COL_NAME  RELATION_COL_NAME
            //
            this.authMap = esbServiceHelperDao.getPrimaryServiceAuthorityFieldMap(serviceID);   //ESB_SERVICE_MAPPER  COMP_CODE、SOURCE_CODE
            //属性 数据类型（“lastUpdateDate ——> date”）
            this.dataTypeMap = esbServiceHelperDao.getPrimaryServiceDataTypeMap(serviceID);     //ESB_SERVICE_MAPPER ——> TB_COL_NAME DATA_TYPE
            //
            this.queryMap = esbServiceHelperDao.getPrimaryServiceQueryableFieldMap(serviceID);      //key:属性名,value:数据类型
        }
    }

    /**
     * 根据value值获得map的key
     *
     * @param map   待处理的对象
     * @param value 值
     * @return key
     */
    private static String valueGetKey(Map map, String value) {
        Set set = map.entrySet();
        String key;
        Iterator it = set.iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            if (entry.getValue().equals(value)) {
                return (String) entry.getKey();
            }
        }
        return null;
    }

    /**
     * get the db colname from the request nodename
     *
     * @param nodeName request node name
     * @return db colname
     */
    public String getColNameFromNode(String nodeName) {
        return valueGetKey(primaryMap, nodeName);
    }

    /**
     * 判断前端发送过来的查询字段是否可以查询
     *
     * @param nodeName 发送过来的查询节点名
     * @return 是否可以查询
     */
    public boolean canQuery(String nodeName) {
        return !(nodeName == null || queryMap == null || "".equals(nodeName.trim()) || !queryMap.containsKey(nodeName.trim()));
    }

    /**
     * 获得需要进行权限认证的字段
     *
     * @return the authority col
     */
    public String getAuthCol() {
        if (authMap == null) return null;
        Set<String> authColKeys = authMap.keySet();
        Iterator<String> iterator = authColKeys.iterator();
        while (iterator.hasNext()) {
            return iterator.next();
        }
        return null;
    }

    /**
     * transfer the node value query from the user to the db type,
     * mainly for the number or date type in db
     *
     * @param nodeName the query node name
     * @param value    the query value
     * @return the sql that can transfer to db type
     */
    public String convert2DbType(String nodeName, String value) {
        if (value == null || "".equals(value.trim())) {
            return null;
        }
        //get node origin col type in db
        String type = dataTypeMap.get(nodeName);
        StringBuilder sb = new StringBuilder();
        //if number
        if (type.equals("number")) {
            sb.append(" TO_NUMBER('").append(value.trim()).append("') ");
        } else if (type.equals("date")) {//if date type000
            sb.append(" TO_DATE('").append(value.trim()).append("','yyyy-mm-dd hh24:mi:ss') ");
        } else {
            sb.append("'").append(value.trim()).append("'");
        }
        return sb.toString();
    }

    //getter and setter
    public String getSelect() {
        return select;
    }

    public void setSelect(String select) {
        this.select = select;
    }

    public String getFrom() {
        return from;
    }

    public void setFrom(String from) {
        this.from = from;
    }

    public String getWhere() {
        return where;
    }

    public void setWhere(String where) {
        this.where = where;
    }

    public Map<String, Map<String, String>> getRelationMap() {
        return relationMap;
    }

    public void setRelationMap(Map<String, Map<String, String>> relationMap) {
        this.relationMap = relationMap;
    }

    public String getTbName() {
        return tbName;
    }

    public void setTbName(String tbName) {
        this.tbName = tbName;
    }

    public Map<String, String> getPrimaryMap() {
        return primaryMap;
    }

    public void setPrimaryMap(Map<String, String> primaryMap) {
        this.primaryMap = primaryMap;
    }

    public Map<String, String> getAliasMap() {
        return aliasMap;
    }

    public void setAliasMap(Map<String, String> aliasMap) {
        this.aliasMap = aliasMap;
    }

    public Map<String, Map<String, String>> getSubMap() {
        return subMap;
    }

    public void setSubMap(Map<String, Map<String, String>> subMap) {
        this.subMap = subMap;
    }
}
